package com.ijiuchuang.jc_localization.view.activity;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.ijiuchuang.jc_localization.R;
import com.ijiuchuang.jc_localization.base.BaseActivity;
import com.ijiuchuang.jc_localization.contract.LocationContract;
import com.ijiuchuang.jc_localization.presenter.LocationPresenter;
import com.ijiuchuang.jc_localization.rx.RxBus;
import com.ijiuchuang.jc_localization.tools.views.LocationView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;

public class LocationActivity extends BaseActivity implements LocationContract.View {

    @BindView(R.id.location_coordinator)
    CoordinatorLayout coordinatorLayout;
    @BindView(R.id.location_toolbar)
    Toolbar toolbar;
    @BindView(R.id.location_fab)
    FloatingActionButton fab;
    @BindView(R.id.location_content)
    RelativeLayout contentView;
    @BindView(R.id.iv_map)
    ImageView mapView;
    @BindView(R.id.location_view)
    LocationView locationView;
    @BindView(R.id.text_log)
    TextView textLog;

    private LocationContract.Presenter presenter;

    // 所有 LocationView
    private List<LocationView> locationViewList = new ArrayList();
    private HashMap<String, LocationView> locationViewHashMap = new HashMap();

    private float scaleX = 0;
    private float scaleY = 0;
    private static double x = 0.0, y = 0.0;

    private static final float PHIC_WIDTH = 19.0f;
    private static final float PHIC_HEIGHT = 19.0f;
    private boolean isAdjusted = false;

    private Observable<String> logObservable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_location);
        ButterKnife.bind(this);

        setSupportActionBar(toolbar);
        toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        initScreenPrePhic();

        xAnimator = new ObjectAnimator();
        xAnimator.setPropertyName("x");
        yAnimator = new ObjectAnimator();
        yAnimator.setPropertyName("y");
        animatorSet = new AnimatorSet();
        animatorSet.playTogether(xAnimator, yAnimator);
        animatorSet.setDuration(2000);

        //addLocalView("No.2");

        presenter = new LocationPresenter(this, this);

        logObservable = RxBus.getInstance().register(String.class);
        logObservable
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onNext(String s) {
                        textLog.setText(s);
                    }
                });
    }

    /**
     * 添加定位View
     */
    private void addLocalView(String mac, String name) {
        LocationView view = new LocationView(this, name);
        view.setTextSize(18);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

        contentView.addView(view, params);
        locationViewList.add(view);
        locationViewHashMap.put(mac, view);
    }

    private void initScreenPrePhic() {
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        scaleX = displayMetrics.widthPixels / PHIC_WIDTH;
        scaleY = displayMetrics.heightPixels / PHIC_HEIGHT;
    }

    @Override
    protected void onStart() {
        super.onStart();

        presenter.start();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus && !isAdjusted) {
            isAdjusted = true;

            presenter.getPoint();
        }
    }

    @Override
    public void setPoint(List<PointF> list) {
        for (int i = 1; i < list.size(); i++) {
            ImageView pos = new ImageView(this);
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            pos.setImageResource(R.drawable.circle);
            contentView.addView(pos, params);

            PointF pointF = list.get(i);
            pos.setX(pointF.x * scaleX - pos.getWidth() / 2);
            pos.setY(pointF.y * scaleY - pos.getWidth() / 2);
        }
    }

    @Override
    public void setMap(Bitmap bitmap) {
        mapView.setImageBitmap(bitmap);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        presenter.onDestroy();
    }

    private ObjectAnimator xAnimator;
    private ObjectAnimator yAnimator;
    private AnimatorSet animatorSet;
    private double px;
    private double py;

    private Handler handler = new Handler();

    public void updatePos(final PointF posXY) {

        final PointF pos = new PointF();
        pos.x = posXY.x;
        pos.y = posXY.y;

        handler.post(new Runnable() {
            @Override
            public void run() {
                x = scaleX * (pos.x + mapView.getX() - 0.3f);
                y = scaleY * pos.y;

                if (px != x || py != y) {
                    px = x;
                    py = y;

                    if (animatorSet.isRunning()) {
                        animatorSet.cancel();
                    }
                    xAnimator.setFloatValues(locationViewList.get(0).getX(), (float) x - 30);
                    yAnimator.setFloatValues(locationViewList.get(0).getY(), (float) y - 100);
                    animatorSet.setTarget(locationViewList.get(0));
                    animatorSet.start();
                }
            }
        });
    }

    @Override
    public void updatePos(final String mac, String name, PointF posXY) {
        if (locationViewHashMap.containsKey(mac)) {
            if (!TextUtils.equals(name, locationViewHashMap.get(mac).getPointName())) {
                locationViewHashMap.get(mac).setPointName(name);
            }

            final PointF pos = new PointF();
            pos.x = posXY.x;
            pos.y = posXY.y;

            final LocationView view = locationViewHashMap.get(mac);

            handler.post(new Runnable() {
                @Override
                public void run() {
                    x = scaleX * (pos.x + mapView.getX() - 0.3f);
                    y = scaleY * pos.y;

                    if (px != x || py != y) {
                        px = x;
                        py = y;

                        if (animatorSet.isRunning()) {
                            animatorSet.cancel();
                        }
                        xAnimator.setFloatValues(view.getX(), (float) px - 15);
                        yAnimator.setFloatValues(view.getY(), (float) py - 85);
                        animatorSet.setTarget(view);
                        animatorSet.start();
                    }
                }
            });
        } else {
            addLocalView(mac, name);
            updatePos(mac, name, posXY);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_location, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        switch (id) {
            case R.id.menu_location_map:
                // pink : later to do sth.
                return true;
            case R.id.menu_location_settings:
                Intent intentSetts = new Intent(this, FragmentActivity.class);
                intentSetts.putExtra(FragmentActivity.FRAGMENT_NAME, FragmentActivity.FRAGMENT_NAME_SETTS_LOCATION);
                startActivity(intentSetts);
                return true;
            case R.id.menu_location_device_list:
                Intent intentDevices = new Intent(this, FragmentActivity.class);
                intentDevices.putExtra(FragmentActivity.FRAGMENT_NAME, FragmentActivity.FRAGMENT_NAME_DEVICE_LIST);
                startActivity(intentDevices);
                return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @OnClick(R.id.location_fab)
    public void onClick(View view) {
        Snackbar.make(coordinatorLayout, "是否建立Socket连接", Snackbar.LENGTH_LONG)
                .setAction("OK", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        socketConnect();
                    }
                })
                .show();
    }

    @Override
    public void socketConnect() {
        presenter.socketConnect();
    }

    @Override
    public void setPresenter(LocationContract.Presenter presenter) {
        this.presenter = presenter;
    }
}
